package armazenador.ip;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;


import jogoBolaoeArmazenador.rn.Bolao;
import jogoBolaoeArmazenador.rn.Jogo;
import jogoBolaoeArmazenador.rn.Usuario;
import jogoBolaoeArmazenador.rn.Volante;

public class IPBolao {
	
	private HashSet<Bolao> buscaBaseadaNa(String query){

		Connection con = null;
		Statement stmRecuperaBolao = null;

		try {
			con = DriverManager.getConnection("jdbc:postgresql://localhost/senaonline","postgres", "bojador");
			stmRecuperaBolao = con.createStatement();

			ResultSet resultSetBoloes = stmRecuperaBolao.executeQuery(query);
			HashSet<Bolao> retornoDaFuncao = new HashSet<Bolao>();
			
			while(resultSetBoloes.next()){
				String login = resultSetBoloes.getString("administrador");
				String nome =  resultSetBoloes.getString("nome");
				int numeroSorteio = resultSetBoloes.getInt("numero_sorteio");
				int numeroDeCotas = resultSetBoloes.getInt("total_de_cotas");
				int ID = resultSetBoloes.getInt("id_bolao");

				
				Statement stmRecuperaAdmBolao = con.createStatement();
				ResultSet resultAdmBolao = stmRecuperaAdmBolao.executeQuery("SELECT nome FROM usuario WHERE usuario.login = '" + login + "'");
				resultAdmBolao.next();
				String administrador = resultAdmBolao.getString("nome");
				
				Bolao novoBolao = new Bolao(new Usuario(administrador));

				
				Statement stmRecuperaVolantes = con.createStatement();
				ResultSet resultSetVolantesDoBolao = stmRecuperaVolantes.executeQuery("SELECT volante.id_volante FROM volante WHERE volante.id_bolao = '" + ID + "'");
				while(resultSetVolantesDoBolao.next()){
					String idVolante = resultSetVolantesDoBolao.getString(1);
					Statement stmRecuperaJogos = con.createStatement();
					ResultSet resultSetJogosDoVolante = stmRecuperaJogos.executeQuery("SELECT jogo.id_jogo FROM jogo WHERE jogo.id_volante = '" + idVolante + "'");
					Volante volante = new Volante(0);
					while(resultSetJogosDoVolante.next()){
						String idJogo = resultSetJogosDoVolante.getString(1);
						Statement stmRecuperaDezenas = con.createStatement();
						ResultSet resultDezenasDoJogo = stmRecuperaDezenas.executeQuery("SELECT dezena.dezena FROM dezena WHERE dezena.id_jogo = '" + idJogo + "'");
						Jogo jogo = new Jogo();
						while(resultDezenasDoJogo.next()){
							jogo.addDezena(resultDezenasDoJogo.getInt(1));
						}
						volante.addJogo(jogo);
					}
					novoBolao.addVolante(volante);
				}
				
				Statement stmRecuperaCotas = con.createStatement();
				ResultSet resultSetCotasDoBolao = stmRecuperaCotas.executeQuery("SELECT cotas.login, cotas.cota FROM cotas WHERE cotas.id_bolao = '" + ID + "'");
				
				HashMap<Usuario, ArrayList<Integer>> map = novoBolao.get_participantes();
				
				while(resultSetCotasDoBolao.next()){
					String id_login = resultSetCotasDoBolao.getString("login");
					int cota = resultSetCotasDoBolao.getInt("cota");
					Usuario donoDaCota = new Usuario(id_login);
					if(map.containsKey(new Usuario(id_login))){
						map.get(donoDaCota).add(cota);
					}else{
						ArrayList<Integer> array = new ArrayList<Integer>();
						array.add(cota);
						map.put(donoDaCota, array);
					}
				}
				
				novoBolao.set_nome(nome);
				novoBolao.set_numeroDoSorteio(numeroSorteio);
				novoBolao.set_totalDeCotas(numeroDeCotas);
				novoBolao.set_ID(ID);
				novoBolao.set_participantes(map);

				retornoDaFuncao.add(novoBolao);
			}
			return retornoDaFuncao;
		} catch (SQLException e) {
			e.printStackTrace();
			return new HashSet<Bolao>();
		} finally{

			try {
				if(stmRecuperaBolao != null)
					stmRecuperaBolao.close();
				if(con != null)
					con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	private int executa(String query){
		Connection con = null;
		Statement stm = null;

		try {
			con = DriverManager.getConnection("jdbc:postgresql://localhost/senaonline","postgres", "bojador");
			stm = con.createStatement();
			ResultSet rs = stm.executeQuery(query);
			rs.next();
			return rs.getInt(1);
		} catch (SQLException e) {
			e.printStackTrace();
			return -1;
		} finally{
			try {
				if(stm != null)
					stm.close();
				if(con != null)
					con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	private void update(String query){
		Connection con = null;
		Statement stm = null;

		try {
			con = DriverManager.getConnection("jdbc:postgresql://localhost/senaonline","postgres", "bojador");
			stm = con.createStatement();
			stm.executeUpdate(query);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally{
			try {
				if(stm != null)
					stm.close();
				if(con != null)
					con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
	
	public HashSet<Bolao> getBoloesAbertos(Usuario user) {

		String query = "SELECT * FROM bolao B WHERE B.total_de_cotas > (SELECT COUNT(*) FROM (SELECT * FROM cotas WHERE cotas.id_bolao = B.id_bolao) AS C) AND NOT(B.administrador = '" + user.get_login() + "')"; 

		return buscaBaseadaNa(query);

	}

	
	public HashSet<Bolao> recuperaHistorico(Usuario user) {
		
		String query = "SELECT * FROM bolao WHERE bolao.administrador = '" + user.get_login() + "'";
		
		return buscaBaseadaNa(query);
		
	}
	
	

public HashSet<Bolao> getBoloesDosQuaisParticipo(Usuario user) {

		String query = "SELECT * FROM bolao, participacao WHERE bolao.id_bolao = participacao.id_bolao AND participacao.login = '" + user.get_login() + "'";
	
		return buscaBaseadaNa(query);
		
	}

	public void criaBolao(Bolao bolao, Usuario administrador) {
		
		String query = "INSERT INTO bolao (administrador, nome, data_criacao, total_de_cotas, numero_sorteio)" +
		"VALUES ('" + administrador.get_login() + "', '" + bolao.get_nome() + "', '" +
				bolao.get_dataDeCriacao() + "', '" + bolao.get_totalDeCotas() + "', '" + bolao.get_numeroDoSorteio() + "') RETURNING bolao.id_bolao";
		
		int idBolaoCriado = executa(query);
		
		HashSet<Volante> volantes = bolao.get_volantes();
		Iterator<Volante> i = volantes.iterator();
		while(i.hasNext()){
			Volante volante = i.next();
			
			query = "INSERT INTO volante (id_bolao) VALUES ('" + Integer.toString(idBolaoCriado) + "') RETURNING volante.id_volante";
			
			int idVolanteCriado = executa(query);
			
			Iterator<Jogo> j = volante.get_jogos().iterator();
			while(j.hasNext()){
				Jogo jogo = j.next();
				
				query = "INSERT INTO jogo (id_volante) VALUES ('" + Integer.toString(idVolanteCriado) + "') RETURNING jogo.id_jogo";
				
				int idJogoCriado = executa(query);
				
				Iterator<Integer> k = jogo.getDezenas().iterator();
				while(k.hasNext()){
					Integer dezena = k.next();
					
					query = "INSERT INTO dezena (dezena, id_jogo) VALUES ('" + Integer.toString(dezena) + "', '" + Integer.toString(idJogoCriado) + "')";
					
					update(query);
				}
			}
		}
	}

	
	public void persistirParticipacao(Bolao bolaoParaEntrar, Usuario novoParticipante, ArrayList<Integer> cotasEscolhidas) {
		
		String query = "INSERT INTO participacao (login, id_bolao) VALUES ('" + novoParticipante.get_login() + "', '" + bolaoParaEntrar.get_ID() + "')";
		
		update(query);
		
		Iterator<Integer> i = cotasEscolhidas.iterator();
		while(i.hasNext()){
			Integer dezena = i.next();
			
			query = "INSERT INTO cotas (cota, login, id_bolao) VALUES ('" + Integer.toString(dezena) + "', '" + novoParticipante.get_login() + "', '" + bolaoParaEntrar.get_ID() + "')";
			
			update(query);
		}
	}


	public void armazenarResultado(Bolao bolao, String stringResultado) {

		String query = "INSERT INTO bolao (resultado) VALUES ('" + stringResultado + "') WHERE id_bolao = '" + bolao.get_ID() + "'";
		
		update(query);
	}
}